package com.pactera.asmp.server.job.dispatch.impl.distribute;

import com.pactera.asmp.server.common.constants.DeviceStatus;
import com.pactera.asmp.server.common.constants.OccupyStatus;
import com.pactera.asmp.server.common.constants.SubTaskStatus;
import com.pactera.asmp.server.common.constants.TaskStatus;
import com.pactera.asmp.server.common.logprint.utils.CollectionUtils;
import com.pactera.asmp.server.dao.*;
import com.pactera.asmp.server.entity.*;
import com.pactera.asmp.server.pojo.DeviceInfo;
import com.pactera.asmp.server.pojo.ScriptInfo;
import com.pactera.asmp.server.pojo.ScriptInfo2;
import com.pactera.asmp.server.pojo.TCanInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Component
public class DistributeDataRepository {

    @Autowired
    private TaskMapper taskMapper;

    @Autowired
    private SubtaskMapper subtaskMapper;

    @Autowired
    private SubtaskDistributeMapper subtaskDistributeMapper;

    @Autowired
    private TaskDeviceMapper taskDeviceMapper;

    @Autowired
    private ScriptInfoMapper scriptInfoMapper;

    @Autowired
    private DeviceInfoMapper deviceInfoMapper;



    public List<Subtask> getExecSubtaskByTaskIdAndDuid(String duid, long taskId){
        List<Subtask> list = new ArrayList<>();
        SubtaskExample example = new SubtaskExample();
        SubtaskExample.Criteria criteria = example.createCriteria().andTaskIdEqualTo(taskId).andDuidEqualTo(duid);
        List<Subtask> subtasks = subtaskMapper.selectByExample(example);
        if(CollectionUtils.isNotEmpty(subtasks)){
            for(Subtask subtask : subtasks){
                if(subtask.getTaskStatus().equals(SubTaskStatus.EXEC.getValue()) ||
                        subtask.getTaskStatus().equals(SubTaskStatus.DISPATCH.getValue())||
                                subtask.getTaskStatus().equals(SubTaskStatus.SEND.getValue())){
                    list.add(subtask);
                }
            }
        }
        return list;
    }


    /**
     * 查询子任务任务
     * @param taskId

     * @return
     */
    public List<Subtask> getSubtaskListByTaskId(Long taskId) {
        SubtaskExample example = new SubtaskExample();
        example.createCriteria().andTaskIdEqualTo(taskId).andIsDeletedEqualTo(0);
        return subtaskMapper.selectByExample(example);
    }
    /**
     * 查询需要其他硬件支持的任务
     * @param taskId
     * @param needCan
     * @param needAuxiliary
     * @return
     */
    public List<Subtask> getSubtaskListNeedSupportByTaskId(Long taskId,boolean needCan,boolean needAuxiliary){
        SubtaskExample example = new SubtaskExample();
        if(needCan && needAuxiliary){
            example.createCriteria().andTaskIdEqualTo(taskId).andNeedCanEqualTo(1).
                    andNeedAuxiliaryEqualTo(1).andIsDeletedEqualTo(0);
        }else if(needCan){
            example.createCriteria().andTaskIdEqualTo(taskId).andNeedCanEqualTo(1).
                    andNeedAuxiliaryEqualTo(0).andIsDeletedEqualTo(0);
        }else if(needAuxiliary){
            example.createCriteria().andTaskIdEqualTo(taskId).andNeedCanEqualTo(0).
                    andNeedAuxiliaryEqualTo(1).andIsDeletedEqualTo(0);
        }else {
            example.createCriteria().andTaskIdEqualTo(taskId).andNeedCanEqualTo(0).
                    andNeedAuxiliaryEqualTo(0).andIsDeletedEqualTo(0);
        }
        example.setOrderByClause(" order_num ASC ");
        return subtaskMapper.selectByExample(example);
    }

    /**
     * 待分发的，且需要支持设备的子任务
     * @param taskId
     * @param needCan
     * @param needAuxiliary
     * @return
     */
    public List<Subtask> getSubtaskListNeedSupportAndWaitSendByTaskId(Long taskId,boolean needCan,boolean needAuxiliary){
        SubtaskExample example = new SubtaskExample();
        if(needCan && needAuxiliary){
            example.createCriteria().
                    andTaskIdEqualTo(taskId).andNeedCanEqualTo(1).andNeedAuxiliaryEqualTo(1).
                    andTaskStatusEqualTo(SubTaskStatus.CREATE.getValue()).andIsDeletedEqualTo(0);
        }else if(needCan){
            example.createCriteria().
                    andTaskIdEqualTo(taskId).andNeedCanEqualTo(1).andNeedAuxiliaryEqualTo(0).
                    andTaskStatusEqualTo(SubTaskStatus.CREATE.getValue()).andIsDeletedEqualTo(0);
        }else if(needAuxiliary){
            example.createCriteria().
                    andTaskIdEqualTo(taskId).andNeedCanEqualTo(0).andNeedAuxiliaryEqualTo(1).
                    andTaskStatusEqualTo(SubTaskStatus.CREATE.getValue()).andIsDeletedEqualTo(0);
        }else {
            example.createCriteria().
                    andTaskIdEqualTo(taskId).andNeedCanEqualTo(0).andNeedAuxiliaryEqualTo(0).
                    andTaskStatusEqualTo(SubTaskStatus.CREATE.getValue()).andIsDeletedEqualTo(0);
        }
        example.setOrderByClause(" order_num ASC ");
        return subtaskMapper.selectByExample(example);
    }

    /**
     * 待分发的，且需要支持设备的子任务
     * @param taskId
     * @param needCan
     * @param needAuxiliary
     * @return
     */
    public List<Subtask> getSubtaskListNeedSupportAndRetryByTaskId(Long taskId,boolean needCan,boolean needAuxiliary){
        SubtaskExample example = new SubtaskExample();
        if(needCan && needAuxiliary){
            example.createCriteria().
                    andTaskIdEqualTo(taskId).andNeedCanEqualTo(1).andNeedAuxiliaryEqualTo(1).
                    andTaskStatusEqualTo(SubTaskStatus.RETRY.getValue()).andIsDeletedEqualTo(0);
        }else if(needCan){
            example.createCriteria().
                    andTaskIdEqualTo(taskId).andNeedCanEqualTo(1).andNeedAuxiliaryEqualTo(0).
                    andTaskStatusEqualTo(SubTaskStatus.RETRY.getValue()).andIsDeletedEqualTo(0);
        }else if(needAuxiliary){
            example.createCriteria().
                    andTaskIdEqualTo(taskId).andNeedCanEqualTo(0).andNeedAuxiliaryEqualTo(1).
                    andTaskStatusEqualTo(SubTaskStatus.RETRY.getValue()).andIsDeletedEqualTo(0);
        }else {
            example.createCriteria().
                    andTaskIdEqualTo(taskId).andNeedCanEqualTo(0).andNeedAuxiliaryEqualTo(0).
                    andTaskStatusEqualTo(SubTaskStatus.RETRY.getValue()).andIsDeletedEqualTo(0);
        }
        example.setOrderByClause(" order_num ASC ");
        return subtaskMapper.selectByExample(example);
    }

    public TaskDTO getTaskById(Integer taskId){
        return taskMapper.getTaskById(taskId);
    }

    public TaskDTO getHistTaskById(Integer taskId){
        return taskMapper.getTaskHistoryById(taskId);
    }

    public int createSubtaskDistribute(SubtaskDistribute subtaskDistribute){
        SubtaskDistributeExample example = new SubtaskDistributeExample();
        example.createCriteria().andTaskIdEqualTo(subtaskDistribute.getTaskId()).andIsDeletedEqualTo(0);
        List<SubtaskDistribute> list = subtaskDistributeMapper.selectByExample(example);
        if(CollectionUtils.isNotEmpty(list)){
            subtaskDistribute.setId(list.get(0).getId());
            return 1;
        }
        return subtaskDistributeMapper.insertSelective(subtaskDistribute);
    }

    public List<TaskDevice> getTaskDeviceListById(Integer taskId){
        TaskDeviceExample taskDeviceExample = new TaskDeviceExample();
        taskDeviceExample.createCriteria().andTaskIdEqualTo(Long.valueOf(taskId)).andIsDeletedEqualTo(0);
        return taskDeviceMapper.selectByExample(taskDeviceExample);
    }

    public List<ScriptInfo2> getScriptInfoListByIdList(List<Integer> scriptIdList){
        return scriptInfoMapper.selectScriptByScriptIds(scriptIdList);
    }

    public DeviceInfo getDeviceByDuid(String duid){
        return deviceInfoMapper.selectByDuid(duid);
    }

    public List<TaskDevice> getFreeDeviceByTaskId(Integer taskId){
        List<TaskDevice> rsltList = new ArrayList<TaskDevice>();
        TaskDeviceExample taskDeviceExample = new TaskDeviceExample();
        taskDeviceExample.createCriteria().andTaskIdEqualTo(Long.valueOf(taskId)).
                andOccupyStatusEqualTo(OccupyStatus.OCCUPIED.getValue()).andIsDeletedEqualTo(0);
        List<TaskDevice> occupyList = taskDeviceMapper.selectByExample(taskDeviceExample);
        if(CollectionUtils.isEmpty(occupyList)) {
            return rsltList;
        }
        for(TaskDevice td: occupyList) {
            DeviceInfo deviceInfo = deviceInfoMapper.selectByDuid(td.getDuid());
            if(deviceInfo.getStatus() == DeviceStatus.FREE.getValue()){//FIXME ???待验证
                rsltList.add(td);
            }
        }
        return rsltList;
    }

    public SubtaskDistribute getSubtaskDistributeByTaskId(Long taskId){
        SubtaskDistributeExample example = new SubtaskDistributeExample();
        example.createCriteria().andTaskIdEqualTo(taskId).andIsDeletedEqualTo(0);
        List<SubtaskDistribute> list = subtaskDistributeMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(list)){
            return null;
        }
        return list.get(0);
    }

    /**
     * 分配结果入库，事务操作
     * @param sd
     * @param list
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor=Exception.class)
    public boolean saveSubtaskAndSD(SubtaskDistribute sd, List<Subtask> list) throws Exception{
        for(Subtask subtask:list){
            if(subtask.getId()==null) {
                int result = subtaskMapper.insertSelective(subtask);
                if (result < 1) {
                    throw new Exception("插入异常");
                }
            }else{
                int result = subtaskMapper.updateByPrimaryKeySelective(subtask);
                if (result < 1) {
                    throw new Exception("更新异常");
                }
            }
        }
        int result = subtaskDistributeMapper.updateByPrimaryKeySelective(sd);
        if(result<1){
            throw new Exception("更新异常");
        }
        return true;
    }

    @Transactional(rollbackFor=Exception.class)
    public boolean saveRetrySubtask(Subtask oldSubtask, Subtask retrySubtask) throws Exception{
        int result = subtaskMapper.updateByPrimaryKeySelective(oldSubtask);
        if(result<1){
            throw new Exception("更新异常");
        }
        result = subtaskMapper.insertSelective(retrySubtask);
        if(result<1){
            throw new Exception("插入异常");
        }
        return true;
    }

    @Transactional(rollbackFor=Exception.class)
    public boolean saveSubtask(Subtask subtask) throws Exception{
        int result = subtaskMapper.updateByPrimaryKeySelective(subtask);
        if(result<1){
            throw new Exception("更新异常");
        }
        return true;
    }

}
